package com.view.cn.mvprxjava.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.view.cn.mvprxjava.R;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 打飞机小游戏
 *
 * SurfaceView好处 : 可以在线程中绘画
 * Created by Zengxiaoping on 2016/12/21.
 */

public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

	private boolean mRunState = false;
	private SurfaceHolder mSurfaceHolder = null;

	//屏幕宽高
	private int mWidth;
	private int mHeight;
	//照片
	private Bitmap mBitmapMy;      //自己
	private Bitmap mBitmapZiDan;   //子弹
	private Bitmap mBitmapDiRen;   //敌人
	private Bitmap mBitmapBg;      //背景
	private Bitmap mBitmapBaoZha;  //爆炸
	private Bitmap mErJiHuanCun;    //二级缓存 : 主要在这个上面绘画和更新

	private MyImage mImage; //我的飞机

	private ArrayList<GameImage> mListGameImage = new ArrayList<>();
	private ArrayList<Zidan> mListZidan = new ArrayList<>();

	public GameView(Context context) {
		super(context);
		getHolder().addCallback(this);//注册回调方法
	}

	public GameView(Context context, AttributeSet attrs) {
		super(context, attrs);
		getHolder().addCallback(this);//注册回调方法
	}

	private void init() {
		mBitmapMy = BitmapFactory.decodeResource(getResources(), R.mipmap.my1);
		mBitmapZiDan = BitmapFactory.decodeResource(getResources(), R.mipmap.zidan);
		mBitmapDiRen = BitmapFactory.decodeResource(getResources(), R.mipmap.diren1);
		mBitmapBg = BitmapFactory.decodeResource(getResources(), R.mipmap.bg);
		mBitmapBaoZha = BitmapFactory.decodeResource(getResources(), R.mipmap.baozha);
		//生产二级缓存照片:在二级缓存上绘画和更新
		mErJiHuanCun = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);

		//先加入背景照片、敌人飞机
		mListGameImage.add(new Beijing(mBitmapBg));
		mImage = new MyImage(mBitmapMy);
		mListGameImage.add(mImage);
		mListGameImage.add(new DijiImage(mBitmapDiRen));
	}


	//视图创建时通知
	@Override
	public void surfaceCreated(SurfaceHolder holder) {

	}

	//界面发生变化的时候通知
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		mWidth = width;
		mHeight = height;
		init();

		mSurfaceHolder = holder;
		mRunState = true;
		new Thread(this).start();
	}

	//销毁的时候通知
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		mRunState = false;
	}

	//绘画中心:只负责绘画
	@Override
	public void run() {
		Paint paint = new Paint();
		int direnNumber = 0;
		try {
			while (true) {

				//加锁：获得绘画的画布
				Canvas canvas = mSurfaceHolder.lockCanvas();
				Canvas newCanvas = new Canvas(mErJiHuanCun);

				//过一会出来一个子弹
				if (direnNumber % 10 == 0) {
					mListZidan.add(new Zidan(mImage, mBitmapZiDan));
				}

				//浅拷贝:防止敌机出屏幕后删除影响到这
				List<GameImage> gameImages = (List<GameImage>) mListGameImage.clone();
				for (GameImage image : gameImages) {
					newCanvas.drawBitmap(image.getBitmap(), image.getX(), image.getY(), paint);
					if (image instanceof DijiImage) {
						((DijiImage) image).shouDaoGongJi((List<Zidan>) mListZidan.clone());// 把子弹告诉敌机
					}
				}

				//子弹集合
				List<GameImage> gameImagesZidan = (List<GameImage>) mListZidan.clone();
				for (GameImage image : gameImagesZidan) {
					newCanvas.drawBitmap(image.getBitmap(), image.getX(), image.getY(), paint);
				}

				//每循环70次就出现一个敌机
				if (direnNumber == 70) {
					direnNumber = 0;
					mListGameImage.add(new DijiImage(mBitmapDiRen));
				}
				direnNumber++;

				canvas.drawBitmap(mErJiHuanCun, 0, 0, paint);
				//解锁:把绘画好的内容提交
				mSurfaceHolder.unlockCanvasAndPost(canvas);

				Thread.sleep(10);
			}
		} catch (Exception e) {

		}
	}

	boolean isClickBitmapMyImageView = false;

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int eventX = (int) event.getX();
		int eventY = (int) event.getY();

		switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:

				//如果手按下的位置到飞机的位置，表示可以移动了
				boolean successY = eventY > mImage.getY() - mBitmapMy.getHeight() / 2 && eventY < mImage.getY() + mBitmapMy.getHeight();
				boolean sucessX = eventX > mImage.getX() - mBitmapMy.getWidth() && eventX < mImage.getX() + mBitmapMy.getWidth();
				if (successY && sucessX) {
					isClickBitmapMyImageView = true;
				}

				break;
			case MotionEvent.ACTION_MOVE:
				//改变我的飞机的位置
				if (isClickBitmapMyImageView) {
					mImage.setX(eventX);
					mImage.setY(eventY);
				}
				break;
			case MotionEvent.ACTION_UP:
				isClickBitmapMyImageView = false;
				break;
		}
		return true;
	}


	//------------------------------------------------------------------------------------------------------------------

	private interface GameImage {
		public Bitmap getBitmap();

		public int getX();

		public int getY();
	}

	//子弹的类：每次出现对象的时候都需要知道飞机的位置
	private class Zidan implements GameImage {

		private MyImage myImage;    //我的飞机的对象
		private Bitmap zidanBitmap; //子弹的图片

		//初始化的子弹的xy坐标
		private int x;
		private int y;

		public Zidan(MyImage myImage, Bitmap zidanBitmap) {
			this.myImage = myImage;
			this.zidanBitmap = zidanBitmap;

			x = myImage.getX() + zidanBitmap.getWidth();
			y = myImage.getY() - zidanBitmap.getHeight();
		}

		@Override
		public Bitmap getBitmap() {
			y -= 9;
			//出屏幕需要删除子弹
			if (y < 0) {
				mListGameImage.remove(this);
			}
			return zidanBitmap;
		}

		@Override
		public int getX() {
			return x;
		}

		@Override
		public int getY() {
			return y;
		}
	}


	//我自己的飞机
	private class MyImage implements GameImage {

		private Bitmap bitmap;
		private List<Bitmap> bitmapListMy = new ArrayList<>();
		//我的飞机初始化的位置
		private int x;
		private int y;

		public MyImage(Bitmap bitmap) {
			this.bitmap = bitmap;
			x = mWidth / 2;
			y = mHeight - bitmap.getHeight();

			bitmapListMy.add(Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()));
		}

		public void setX(int x) {
			this.x = x;
		}

		public void setY(int y) {
			this.y = y;
		}

		@Override
		public Bitmap getBitmap() {
			Bitmap bitmap = bitmapListMy.get(0);
			return bitmap;
		}

		@Override
		public int getX() {
			return x;
		}

		@Override
		public int getY() {
			return y;
		}
	}

	//敌机对象的类
	private class DijiImage implements GameImage {

		private Bitmap bitmapDiRen;
		private List<Bitmap> bitmapList = new ArrayList<>();

		private int index = 0;
		private int num = 0;
		//飞机刚出来的位置
		private int x;
		private int y;

		public DijiImage(Bitmap bitmapDiRen) {
			this.bitmapDiRen = bitmapDiRen;
			y = -bitmapDiRen.getHeight();
			x = new Random().nextInt(mWidth - bitmapDiRen.getWidth() / 4);

			bitmapList.add(Bitmap.createBitmap(bitmapDiRen, 0, 0, bitmapDiRen.getWidth(), bitmapDiRen.getHeight()));
//			bitmapList.add(Bitmap.createBitmap(bitmapDiRen, (bitmapDiRen.getWidth() / 4) * 1, 0, bitmapDiRen.getWidth() / 4, bitmapDiRen.getHeight()));
//			bitmapList.add(Bitmap.createBitmap(bitmapDiRen, (bitmapDiRen.getWidth() / 4) * 2, 0, bitmapDiRen.getWidth() / 4, bitmapDiRen.getHeight()));
//			bitmapList.add(Bitmap.createBitmap(bitmapDiRen, (bitmapDiRen.getHeight() / 4) * 2, 0, bitmapDiRen.getWidth() / 4, bitmapDiRen.getHeight()));
		}

		@Override
		public Bitmap getBitmap() {
			Bitmap bitmap = bitmapList.get(index);
			if (num == 4) {
				index++;
				if (index == bitmapList.size()) {
					index = 0;
				}
				num = 0;
			}
			y += 2;
			num++;

			//出屏幕需要删除敌机
			if (y > mHeight) {
				mListGameImage.remove(this);
			}
			return bitmap;
		}

		@Override
		public int getX() {
			return x;
		}

		@Override
		public int getY() {
			return y;
		}

		/**
		 * 地方机器受到攻击
		 *
		 * @param gameImagesZidan 子彈集合
		 */
		public void shouDaoGongJi(List<Zidan> gameImagesZidan) {
//			boolean successY = false;
//			boolean successX = false;
//			for (Zidan zidan : gameImagesZidan) {
//				successY = zidan.getY() > y - bitmapDiRen.getHeight() / 2 && zidan.getY() < y + bitmapDiRen.getHeight() / 2;
//				successX = zidan.getX() > x - bitmapDiRen.getWidth() / 2 && zidan.getX() < y + bitmapDiRen.getWidth() / 2;
//				if (successY && successX) {
//					mListGameImage.remove(this);
//					gameImagesZidan.remove(zidan);
//					break;
//				}
//			}
			for (GameImage zidan : gameImagesZidan) {
				if (zidan.getX() > x - bitmapDiRen.getWidth() / 2
						&& zidan.getY() > y - y + bitmapDiRen.getHeight() / 2
						&& zidan.getX() < x + bitmapDiRen.getWidth() / 2
						&& zidan.getY() < y + bitmapDiRen.getHeight() / 2) {

					mListZidan.remove(zidan);
					mListGameImage.remove(this);
					break;
				}

			}
		}
	}

	//背景处理的类
	private class Beijing implements GameImage {
		private Bitmap bg;
		private Bitmap newBitmap = null;
		private int height = 0;

		private Beijing(Bitmap bg) {
			this.bg = bg;
			newBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
		}


		@Override
		public Bitmap getBitmap() {

			Paint paint = new Paint();
			Canvas canvas = new Canvas(newBitmap);
			canvas.drawBitmap(
					bg,
					new Rect(0, 0, bg.getWidth(), bg.getHeight()),
					new Rect(0, height, mWidth, mHeight + height),
					paint);

			canvas.drawBitmap(
					bg,
					new Rect(0, 0, bg.getWidth(), bg.getHeight()),
					new Rect(0, -mHeight + height, mWidth, height),
					paint);

			height++;
			if (height == mHeight) {
				height = 0;
			}
			return newBitmap;
		}

		@Override
		public int getX() {
			return 0;
		}

		@Override
		public int getY() {
			return 0;
		}
	}

}
